/**
 * Tab Workspace Manager - Popup Script
 * 标签页工作区管理器 - 弹出窗口脚本
 * 
 * 文件描述：
 * 这是Chrome扩展的弹出窗口主要逻辑文件，负责处理用户界面交互和工作区管理功能。
 * 
 * 主要功能：
 * - 保存当前窗口的所有标签页为工作区（支持两种保存模式）
 * - 管理和浏览已保存的工作区列表
 * - 搜索和过滤工作区
 * - 恢复工作区中的标签页到新窗口或当前窗口
 * - 编辑工作区名称和标签页列表
 * - 删除工作区（带确认机制）
 * - 实时显示当前标签页数量
 * - 响应式UI交互和状态管理
 * 
 * 技术特点：
 * - 使用Chrome Extension API进行标签页和存储管理
 * - 模块化的类设计，便于维护和扩展
 * - 完整的错误处理和用户反馈机制
 * - 支持键盘快捷键和无障碍访问
 * 
 * @author Tab Workspace Manager Team
 * @version 1.0.0
 * @since 2024
 */

// TabWorkspace Manager - 主要功能实现

/**
 * TabWorkspaceManager 类
 * 标签页工作区管理器的核心类，负责所有工作区相关的操作和UI管理
 */
class TabWorkspaceManager {
  /**
   * 构造函数 - 初始化管理器实例
   * 设置初始状态变量并启动初始化流程
   */
  constructor() {
    // 存储所有工作区数据
    this.currentWorkspaces = [];
    // 存储搜索过滤后的工作区数据
    this.filteredWorkspaces = [];
    // 当前窗口的标签页数量
    this.currentTabCount = 0;
    // 当前正在编辑的工作区对象
    this.editingWorkspace = null;
    
    // 启动初始化流程
    this.init();
  }

  /**
   * 异步初始化方法
   * 按顺序执行所有必要的初始化步骤
   */
  async init() {
    // 从存储中加载工作区数据
    await this.loadWorkspaces();
    // 获取并显示当前标签页数量
    await this.updateTabCount();
    // 设置所有事件监听器
    this.setupEventListeners();
    // 设置标签页切换功能
    this.setupTabSwitching();
    // 渲染工作区列表到界面
    this.renderWorkspacesList();
  }

  /**
   * 设置所有事件监听器
   * 为页面上的各种UI元素绑定相应的事件处理函数
   */
  setupEventListeners() {
    // 标签页切换事件
    document.getElementById('tab-save').addEventListener('click', () => this.switchTab('save'));
    document.getElementById('tab-workspaces').addEventListener('click', () => this.switchTab('workspaces'));

    // 保存工作区按钮事件
    document.getElementById('save-workspace').addEventListener('click', () => this.saveWorkspace());

    // 搜索工作区输入框事件
    document.getElementById('search-workspace').addEventListener('input', (e) => this.searchWorkspaces(e.target.value));

    // 所有模态框的关闭按钮事件
    document.querySelectorAll('.close-modal').forEach(btn => {
      btn.addEventListener('click', () => this.closeAllModals());
    });

    // 工作区详情模态框操作按钮事件
    document.getElementById('restore-current-window').addEventListener('click', () => this.restoreWorkspace(false));
    document.getElementById('restore-new-window').addEventListener('click', () => this.restoreWorkspace(true));
    document.getElementById('edit-workspace').addEventListener('click', () => this.openEditModal());
    document.getElementById('delete-workspace').addEventListener('click', () => this.openDeleteModal());

    // 编辑工作区模态框操作按钮事件
    document.getElementById('save-edit').addEventListener('click', () => this.saveWorkspaceEdit());
    document.getElementById('cancel-edit').addEventListener('click', () => this.closeAllModals());
    document.getElementById('add-tab-btn').addEventListener('click', () => this.addNewTab());

    // 确认删除模态框操作按钮事件
    document.getElementById('confirm-delete').addEventListener('click', () => this.deleteWorkspace());
    document.getElementById('cancel-delete').addEventListener('click', () => this.closeAllModals());

    // 点击模态框背景区域关闭模态框
    document.querySelectorAll('.modal').forEach(modal => {
      modal.addEventListener('click', (e) => {
        if (e.target === modal) {
          this.closeAllModals();
        }
      });
    });

    // 工作区名称输入验证事件
    document.getElementById('workspace-name').addEventListener('input', (e) => {
      this.validateWorkspaceName(e.target.value);
    });

    // 监听来自background script的消息
    // 当标签页数量发生变化时更新显示
    chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
      if (message.type === 'TAB_COUNT_CHANGED') {
        this.updateTabCount();
      }
    });
  }

  /**
   * 设置标签页切换功能
   * 处理保存面板和工作区列表面板之间的切换
   */
  setupTabSwitching() {
    const tabButtons = document.querySelectorAll('.tab-btn');
    const tabPanels = document.querySelectorAll('.tab-panel');

    // 为每个标签按钮添加点击事件
    tabButtons.forEach(btn => {
      btn.addEventListener('click', () => {
        const targetTab = btn.dataset.tab;
        
        // 移除所有标签按钮和面板的活动状态
        tabButtons.forEach(b => b.classList.remove('active'));
        tabPanels.forEach(p => p.classList.remove('active'));
        
        // 激活当前点击的标签按钮和对应面板
        btn.classList.add('active');
        document.getElementById(`${targetTab}-panel`).classList.add('active');
        
        // 如果切换到工作区列表面板，刷新工作区列表显示
        if (targetTab === 'workspaces') {
          this.renderWorkspacesList();
        }
      });
    });
  }

  // 切换标签页
  switchTab(tabName) {
    // 更新标签按钮状态
    document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active'));
    document.getElementById(`tab-${tabName}`).classList.add('active');

    // 更新面板显示
    document.querySelectorAll('.panel').forEach(panel => panel.classList.remove('active'));
    document.getElementById(`${tabName}-panel`).classList.add('active');

    // 如果切换到工作区面板，刷新列表
    if (tabName === 'workspaces') {
      this.renderWorkspacesList();
    }
  }

  /**
   * 更新当前窗口的标签页数量显示
   * 获取当前窗口标签页数量并更新UI显示
   */
  async updateTabCount() {
    try {
      // 向background script发送获取标签页数量的消息
      const result = await chrome.runtime.sendMessage({type: 'GET_TAB_COUNT'});
      this.currentTabCount = result.count || 0;
      // 更新页面上的标签页数量显示
      document.getElementById('current-tabs-count').textContent = this.currentTabCount;
    } catch (error) {
      console.error('获取标签页数量失败:', error);
      // 出错时显示0
      this.currentTabCount = 0;
      document.getElementById('current-tabs-count').textContent = '0';
    }
  }

  // 验证标签页是否有效
  isValidTab(tab) {
    const invalidProtocols = ['chrome://', 'chrome-extension://', 'edge://', 'about:'];
    return !invalidProtocols.some(protocol => tab.url.startsWith(protocol));
  }

  // 验证工作区名称
  validateWorkspaceName(name) {
    const saveBtn = document.getElementById('save-workspace');
    const input = document.getElementById('workspace-name');
    
    if (!name.trim()) {
      saveBtn.disabled = true;
      input.style.borderColor = '#dc3545';
      return false;
    }

    // 检查名称是否重复
    const isDuplicate = this.currentWorkspaces.some(ws => ws.name === name.trim());
    if (isDuplicate) {
      saveBtn.disabled = true;
      input.style.borderColor = '#dc3545';
      this.showStatus('工作区名称已存在', 'error');
      return false;
    }

    saveBtn.disabled = false;
    input.style.borderColor = '#28a745';
    this.hideStatus();
    return true;
  }

  /**
   * 保存当前窗口的标签页为工作区
   * 验证输入，获取当前标签页，并保存到存储中
   */
  async saveWorkspace() {
    const nameInput = document.getElementById('workspace-name');
    const name = nameInput.value.trim();
    
    if (!this.validateWorkspaceName(name)) {
      return;
    }

    const saveMode = document.querySelector('input[name="save-mode"]:checked').value;
    
    try {
      this.showStatus('正在保存工作区...', 'info');
      
      // 获取当前所有标签页
      const tabs = await chrome.tabs.query({ currentWindow: true });
      const validTabs = tabs.filter(tab => this.isValidTab(tab));
      
      if (validTabs.length === 0) {
        this.showStatus('没有可保存的标签页', 'error');
        return;
      }

      // 构建工作区数据
      const workspace = {
        id: this.generateId(),
        name: name,
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString(),
        saveMode: saveMode,
        tabs: []
      };

      // 处理每个标签页
      for (const tab of validTabs) {
        const tabData = {
          url: tab.url,
          title: tab.title,
          favicon: tab.favIconUrl || '',
          addedAt: new Date().toISOString()
        };

        // 如果选择缓存模式，获取页面内容
        if (saveMode === 'cache') {
          try {
            const content = await this.getPageContent(tab.id);
            tabData.cachedContent = content;
          } catch (error) {
            console.warn(`无法缓存标签页 ${tab.url}:`, error);
          }
        }

        workspace.tabs.push(tabData);
      }

      // 保存到存储
      this.currentWorkspaces.push(workspace);
      await this.saveWorkspaces();
      
      this.showStatus(`成功保存工作区 "${name}"，包含 ${workspace.tabs.length} 个标签页`, 'success');
      nameInput.value = '';
      
      // 切换到工作区列表
      setTimeout(() => {
        this.switchTab('workspaces');
      }, 1500);
      
    } catch (error) {
      console.error('保存工作区失败:', error);
      this.showStatus('保存工作区失败，请重试', 'error');
    }
  }

  // 获取页面内容（用于缓存）
  async getPageContent(tabId) {
    return new Promise((resolve, reject) => {
      chrome.tabs.sendMessage(tabId, { action: 'getPageContent' }, (response) => {
        if (chrome.runtime.lastError) {
          reject(chrome.runtime.lastError);
        } else {
          resolve(response?.content || '');
        }
      });
    });
  }

  /**
   * 从存储中加载工作区数据
   * 通过background script获取所有已保存的工作区
   */
  async loadWorkspaces() {
    try {
      // 向background script发送获取工作区的消息
      const result = await chrome.runtime.sendMessage({type: 'GET_WORKSPACES'});
      // 更新当前工作区数据和过滤后的数据
      this.currentWorkspaces = result.workspaces || [];
      this.filteredWorkspaces = [...this.currentWorkspaces];
    } catch (error) {
      console.error('加载工作区失败:', error);
      // 出错时初始化为空数组
      this.currentWorkspaces = [];
      this.filteredWorkspaces = [];
    }
  }

  // 保存工作区列表
  async saveWorkspaces() {
    try {
      await chrome.storage.local.set({ workspaces: this.currentWorkspaces });
    } catch (error) {
      console.error('保存工作区失败:', error);
      throw error;
    }
  }

  /**
   * 渲染工作区列表到页面
   * 根据当前过滤后的工作区数据生成HTML并绑定事件
   */
  renderWorkspacesList(searchTerm = '') {
    const container = document.getElementById('workspaces-container');
    
    // 过滤工作区
    let filteredWorkspaces = this.currentWorkspaces;
    if (searchTerm) {
      filteredWorkspaces = this.currentWorkspaces.filter(ws => 
        ws.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
        ws.tabs.some(tab => 
          tab.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
          tab.url.toLowerCase().includes(searchTerm.toLowerCase())
        )
      );
    }

    // 如果没有工作区，显示空状态
    if (filteredWorkspaces.length === 0) {
      container.innerHTML = `
        <div class="empty-state">
          <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round">
            <rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect>
            <line x1="8" y1="21" x2="16" y2="21"></line>
            <line x1="12" y1="17" x2="12" y2="21"></line>
          </svg>
          <p>${searchTerm ? '未找到匹配的工作区' : '暂无保存的工作区'}</p>
          <p class="empty-state-sub">${searchTerm ? '尝试其他搜索词' : '点击"保存"标签创建您的第一个工作区'}</p>
        </div>
      `;
      return;
    }

    // 按创建时间倒序排列（最新的在前面）
    filteredWorkspaces.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));

    // 生成工作区卡片HTML
    container.innerHTML = filteredWorkspaces.map(workspace => `
      <div class="workspace-card" data-workspace-id="${workspace.id}">
        <h3>${this.escapeHtml(workspace.name)}</h3>
        <div class="workspace-meta">
          <span>${this.formatDate(workspace.createdAt)}</span>
          <span class="tabs-count">${workspace.tabs.length} 个标签页</span>
        </div>
      </div>
    `).join('');

    // 为每个工作区卡片添加点击事件
    container.querySelectorAll('.workspace-card').forEach(card => {
      // 点击卡片打开工作区详情
      card.addEventListener('click', () => {
        const workspaceId = card.dataset.workspaceId;
        this.openWorkspaceDetail(workspaceId);
      });
    });
  }

  /**
   * 搜索工作区功能
   * 根据搜索关键词过滤工作区列表并重新渲染
   * @param {string} searchTerm - 搜索关键词
   */
  searchWorkspaces(searchTerm) {
    // 直接调用渲染方法，传入搜索词进行过滤
    this.renderWorkspacesList(searchTerm);
  }

  /**
   * 打开工作区详情模态框
   * 显示工作区的详细信息和标签页列表
   * @param {string} workspaceId - 工作区ID
   */
  openWorkspaceDetail(workspaceId) {
    const workspace = this.currentWorkspaces.find(ws => ws.id === workspaceId);
    if (!workspace) return;

    this.currentWorkspace = workspace;
    
    // 填充工作区基本信息到模态框
    document.getElementById('detail-workspace-name').textContent = workspace.name;
    document.getElementById('detail-created-time').textContent = this.formatDate(workspace.createdAt);
    document.getElementById('detail-tabs-count').textContent = workspace.tabs.length;

    // 渲染工作区中的标签页列表
    const tabsContainer = document.getElementById('detail-tabs-container');
    tabsContainer.innerHTML = workspace.tabs.map(tab => `
      <div class="tab-item">
        <img class="tab-favicon" src="${tab.favicon || 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="%23999" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>'}" onerror="this.src='data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"%23999\" d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\"/></svg>'">
        <div class="tab-info">
          <div class="tab-title">${this.escapeHtml(tab.title)}</div>
          <div class="tab-url">${this.escapeHtml(tab.url)}</div>
        </div>
      </div>
    `).join('');

    // 显示工作区详情模态框
    this.showModal('workspace-detail-modal');
  }

  /**
   * 恢复工作区中的所有标签页
   * 在新窗口或当前窗口中打开工作区中保存的所有标签页
   * @param {boolean} newWindow - 是否在新窗口中恢复，默认false（当前窗口）
   */
  async restoreWorkspace(newWindow = false) {
    if (!this.currentWorkspace) return;

    try {
      this.showStatus('正在恢复工作区...', 'info');
      
      const tabs = this.currentWorkspace.tabs;
      if (tabs.length === 0) {
        this.showStatus('工作区中没有标签页', 'error');
        return;
      }

      if (newWindow) {
        // 在新窗口中恢复
        const window = await chrome.windows.create({
          url: tabs[0].url,
          focused: true
        });
        
        // 添加其余标签页
        for (let i = 1; i < tabs.length; i++) {
          await chrome.tabs.create({
            windowId: window.id,
            url: tabs[i].url,
            active: false
          });
        }
      } else {
        // 在当前窗口中恢复
        for (const tab of tabs) {
          await chrome.tabs.create({
            url: tab.url,
            active: false
          });
        }
      }

      this.showStatus(`成功恢复工作区 "${this.currentWorkspace.name}"`, 'success');
      this.closeAllModals();
      
      // 关闭扩展窗口
      setTimeout(() => {
        window.close();
      }, 1000);
      
    } catch (error) {
      console.error('恢复工作区失败:', error);
      this.showStatus('恢复工作区失败，请重试', 'error');
    }
  }

  /**
   * 打开编辑工作区模态框
   * 允许用户修改工作区名称和管理标签页列表
   */
  openEditModal() {
    if (!this.currentWorkspace) return;
    
    // 深拷贝当前工作区数据，避免直接修改原数据
    this.editingWorkspace = JSON.parse(JSON.stringify(this.currentWorkspace));
    
    // 填充编辑表单的工作区名称
    document.getElementById('edit-name-input').value = this.editingWorkspace.name;
    
    // 渲染可编辑的标签页列表（带删除按钮）
    this.renderEditableTabsList();
    
    // 关闭其他模态框，显示编辑模态框
    this.closeAllModals();
    this.showModal('edit-workspace-modal');
  }

  // 渲染可编辑的标签页列表
  renderEditableTabsList() {
    const container = document.getElementById('edit-tabs-container');
    
    container.innerHTML = this.currentWorkspace.tabs.map((tab, index) => `
      <div class="tab-item" data-tab-index="${index}">
        <img class="tab-favicon" src="${tab.favicon || 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="%23999" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>'}" onerror="this.src='data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"%23999\" d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\"/></svg>'">
        <div class="tab-info">
          <div class="tab-title">${this.escapeHtml(tab.title)}</div>
          <div class="tab-url">${this.escapeHtml(tab.url)}</div>
        </div>
        <div class="tab-actions">
          <button class="tab-action-btn delete" onclick="tabWorkspaceManager.removeTab(${index})">
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
              <polyline points="3,6 5,6 21,6"></polyline>
              <path d="m19,6v14a2,2 0 0,1 -2,2H7a2,2 0 0,1 -2,-2V6m3,0V4a2,2 0 0,1 2,-2h4a2,2 0 0,1 2,2v2"></path>
              <line x1="10" y1="11" x2="10" y2="17"></line>
              <line x1="14" y1="11" x2="14" y2="17"></line>
            </svg>
          </button>
        </div>
      </div>
    `).join('');
  }

  // 删除标签页
  removeTab(index) {
    if (!this.currentWorkspace || index < 0 || index >= this.currentWorkspace.tabs.length) return;
    
    this.currentWorkspace.tabs.splice(index, 1);
    this.renderEditableTabsList();
  }

  // 添加新标签页
  addNewTab() {
    const urlInput = document.getElementById('add-tab-url');
    const titleInput = document.getElementById('add-tab-title');
    
    const url = urlInput.value.trim();
    const title = titleInput.value.trim();
    
    if (!url) {
      this.showStatus('请输入URL', 'error');
      return;
    }

    // 验证URL格式
    try {
      new URL(url);
    } catch {
      this.showStatus('请输入有效的URL', 'error');
      return;
    }

    const newTab = {
      url: url,
      title: title || url,
      favicon: '',
      addedAt: new Date().toISOString()
    };

    this.currentWorkspace.tabs.push(newTab);
    this.renderEditableTabsList();
    
    // 清空输入框
    urlInput.value = '';
    titleInput.value = '';
    
    this.showStatus('标签页添加成功', 'success');
  }

  // 保存工作区编辑
  async saveWorkspaceEdit() {
    const newName = document.getElementById('edit-name-input').value.trim();
    
    if (!newName) {
      this.showStatus('请输入工作区名称', 'error');
      return;
    }

    // 检查名称是否重复（排除当前工作区）
    const isDuplicate = this.currentWorkspaces.some(ws => 
      ws.id !== this.currentWorkspace.id && ws.name === newName
    );
    
    if (isDuplicate) {
      this.showStatus('工作区名称已存在', 'error');
      return;
    }

    try {
      // 更新工作区信息
      this.currentWorkspace.name = newName;
      this.currentWorkspace.updatedAt = new Date().toISOString();
      
      // 保存到存储
      await this.saveWorkspaces();
      
      this.showStatus('工作区更新成功', 'success');
      this.closeAllModals();
      this.renderWorkspacesList();
      
    } catch (error) {
      console.error('保存工作区编辑失败:', error);
      this.showStatus('保存失败，请重试', 'error');
    }
  }

  // 打开删除确认模态框
  openDeleteModal() {
    if (!this.currentWorkspace) return;
    
    document.getElementById('delete-workspace-name').textContent = this.currentWorkspace.name;
    this.closeAllModals();
    this.showModal('confirm-delete-modal');
  }

  // 删除工作区
  async deleteWorkspace() {
    if (!this.currentWorkspace) return;

    try {
      const index = this.currentWorkspaces.findIndex(ws => ws.id === this.currentWorkspace.id);
      if (index !== -1) {
        this.currentWorkspaces.splice(index, 1);
        await this.saveWorkspaces();
        
        this.showStatus(`工作区 "${this.currentWorkspace.name}" 已删除`, 'success');
        this.closeAllModals();
        this.renderWorkspacesList();
        this.currentWorkspace = null;
      }
    } catch (error) {
      console.error('删除工作区失败:', error);
      this.showStatus('删除失败，请重试', 'error');
    }
  }

  // 显示模态框
  showModal(modalId) {
    document.getElementById(modalId).classList.add('show');
  }

  // 关闭所有模态框
  closeAllModals() {
    document.querySelectorAll('.modal').forEach(modal => {
      modal.classList.remove('show');
    });
  }

  // 显示状态消息
  showStatus(message, type = 'info') {
    const statusEl = document.getElementById('save-status');
    statusEl.textContent = message;
    statusEl.className = `status-message ${type}`;
    statusEl.style.display = 'block';
    
    // 自动隐藏成功和信息消息
    if (type === 'success' || type === 'info') {
      setTimeout(() => this.hideStatus(), 3000);
    }
  }

  // 隐藏状态消息
  hideStatus() {
    const statusEl = document.getElementById('save-status');
    statusEl.style.display = 'none';
  }

  // 工具函数
  generateId() {
    return Date.now().toString(36) + Math.random().toString(36).substr(2);
  }

  formatDate(dateString) {
    const date = new Date(dateString);
    const now = new Date();
    const diffMs = now - date;
    const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
    
    if (diffDays === 0) {
      return '今天';
    } else if (diffDays === 1) {
      return '昨天';
    } else if (diffDays < 7) {
      return `${diffDays}天前`;
    } else {
      return date.toLocaleDateString('zh-CN');
    }
  }

  escapeHtml(text) {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
  }
}

// 初始化应用
let tabWorkspaceManager;

document.addEventListener('DOMContentLoaded', () => {
  tabWorkspaceManager = new TabWorkspaceManager();
});

// 导出到全局作用域（用于HTML中的onclick事件）
window.tabWorkspaceManager = tabWorkspaceManager;